package cc.vv.lkbasecomponent.base.ui;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.IdRes;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

import cc.vv.lkbasecomponent.R;
import cc.vv.lkbasecomponent.base.ui.loading.InterLoading;
import cc.vv.lkbasecomponent.base.ui.loading.LKBaseLoading;
import cc.vv.lkbasecomponent.http.lib.CallBack;
import cc.vv.lkbasecomponent.http.lib.wrap.LKCall;
import cc.vv.lklibrary.anno.NPFInject;
import cc.vv.lklibrary.log.LogOperate;

/**
 * Basefragment
 *
 * @author dupeng dupeng@vv.cc
 * @date 2018/3/9
 */

public abstract class LKBaseFragment extends Fragment {

    public LKBaseActivity mActivity;

    private View mRootView;

    /**
     * 防止内存泄漏 的handler
     */
    private WeakHandler mWeakHandler;

    /**
     * 存放广播接收器，onDestroy中，会把list中的广播取消注册，清空。
     */
    private ArrayList<BroadcastReceiver> mBroadcastReceivers;

    boolean isViewPrepare = false;
    private boolean isFirstVisible = true;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getActivity() instanceof LKBaseActivity) {
            mActivity = (LKBaseActivity) getActivity();
        }
    }

    /**
     * findViewById()
     *
     * @param id
     * @return
     */
    public final View lkFindViewById(int id) {
        if (mRootView != null) {
            return mRootView.findViewById(id);
        }
        return null;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (!isViewPrepare) {
            //还没准备好,因为此方法可能在声明周期外.
            return;
        }

        if (isVisibleToUser) {
            if (isFirstVisible) {
                //第一次，且用户可见
                onFirstVisible();
                isFirstVisible = false;
            } else {
                //可见，但不是第一次
                onVisible();
            }
        }

    }

    /**
     * 不是第一次进入fragment
     */
    protected void onVisible() {

    }

    /**
     * 第一次进入fragment
     */
    protected void onFirstVisible() {
        Bundle arguments = getArguments();
        initView(arguments);
        initData(arguments);
        initAction(arguments);
    }

    protected abstract void initView(Bundle arguments);

    protected void initData(Bundle arguments) {
    }

    protected void initAction(Bundle arguments) {
    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (!isViewPrepare) {
            isViewPrepare = true;
            if (getUserVisibleHint()) {
                if (isFirstVisible) {
                    onFirstVisible();
                    isFirstVisible = false;
                } else {
                    onVisible();
                }
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isViewPrepare = false;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mActivity.getLoading().addPierceViews(initLoadingPierceViews());
        //这里用来防止onDestroyView后,view都没了.
        if (mRootView == null) {
            mRootView = NPFInject.getInstance().inject(this, inflater, container);
        }
        ViewGroup parent = (ViewGroup) mRootView.getParent();
        if (parent != null) {
            parent.removeView(mRootView);
        }
        return mRootView;
    }


    /***************************************************************************/
    /******************************简化相关方法START********************************/
    /***************************************************************************/
    /**
     * 获取防内存泄漏Handler
     *
     * @return 防内存泄漏的Handler
     */
    public final synchronized WeakHandler getHandler() {
        if (mWeakHandler == null) {
            mWeakHandler = new WeakHandler(this);
        }
        return mWeakHandler;
    }

    /**
     * handle防内存泄漏Handler数据
     *
     * @param msg 消息
     */
    protected void onHandleMsg(Message msg) {
    }

    /**
     * 添加fragment到指定id
     *
     * @param containerViewId 放fragment的控件
     * @param fragment        Fragment
     * @param tag             标识
     */
    public final void addFragment(@IdRes int containerViewId, Fragment fragment, @Nullable String tag) {
        try {
            FragmentManager supportFragmentManager = getActivity().getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
            fragmentTransaction.add(containerViewId, fragment, tag);
            fragmentTransaction.commitNowAllowingStateLoss();
        } catch (Exception e) {
            LogOperate.e(e.getMessage());
        }
    }

    /**
     * activity跳转方法
     *
     * @param activityClass 要跳转的activity.class
     * @param bundle        传递数据
     */
    public final void lkStartActivity(@NonNull Class<? extends Activity> activityClass, @Nullable Bundle bundle) {
        if (mActivity != null) {
            mActivity.lkStartActivity(activityClass, bundle);
        }
    }

    /**
     * activity for result 跳转方法
     *
     * @param activityClass
     * @param requestCode
     * @param bundle
     */
    public final void lkStartActivityForResult(@NonNull Class<? extends Activity> activityClass, int requestCode, @Nullable Bundle bundle) {
        if (mActivity != null) {
            mActivity.lkStartActivityForResult(activityClass, requestCode, bundle);
        }
    }

    /**
     * 发送广播 方法
     *
     * @param action
     * @param bundle
     */
    public final void lkSendBroadcast(String action, Bundle bundle) {
        if (mActivity != null) {
            mActivity.lkSendBroadcast(action, bundle);
        }
    }

    /**
     * 注册广播接收器
     *
     * @param isSelfDestroy true：在onDestroy时，框架帮你取消注册广播。false：自己来
     * @param receiver
     * @param actions
     */
    public final void lkRegisterReceiver(boolean isSelfDestroy, BroadcastReceiver receiver, String... actions) {
        if (actions == null || actions.length <= 0) {
            LogOperate.e("注册广播失败,action 为空!");
            return;
        }
        if (isSelfDestroy) {
            //好吧，由框架在destroy时，帮你取消注册广播.将广播放到list中。
            if (mBroadcastReceivers == null) {
                mBroadcastReceivers = new ArrayList<>(3);
            }
            if (receiver != null && !mBroadcastReceivers.contains(receiver)) {
                mBroadcastReceivers.add(receiver);
            }
        }
        IntentFilter intentFilter = new IntentFilter();
        for (String action : actions) {
            intentFilter.addAction(action);
        }
        getActivity().registerReceiver(receiver, intentFilter);
    }
    /***************************************************************************/
    /******************************简化相关方法END********************************/
    /***************************************************************************/

    /**
     * 重写此方法，来自定义Loading
     *
     * @return
     */
    public InterLoading getLoading() {
        if (mActivity == null) {
            return new LKBaseLoading(R.layout.view_base_loading);
        }
        return mActivity.getLoading();
    }

    /**
     * 重写此方法，返回可穿透点击的views。也可以主动调用loading添加views方法。
     *
     * @return
     */
    protected View[] initLoadingPierceViews() {
        return null;
    }

    /**
     * 重写此方法，返回是否可 触摸 穿透loading层。也可以主动调用loading 方法去实时设置。
     *
     * @return
     */
    protected boolean initCanPierce() {
        return false;
    }

    /***************************************************************************/
    /******************************网络相关方法START********************************/
    /***************************************************************************/
    /**
     * 返回默认callBack。也可以new BaseCallBack() 进行回调重写.
     *
     * @param <T>
     * @return
     */
    public <T> BaseCallBack<T> defCallBack() {
        return new BaseCallBack<>(this);
    }

    /**
     * 请求成功回调方法.
     * <br>
     * 也可以重写onSuccess()回调
     *
     * @param url 请求的地址
     * @param obj 返回的实体类
     */
    protected void onRequestSuccess(String url, Object obj) {
    }

    /**
     * 请求开始回调
     *
     * @param url
     * @param isLoading
     */
    protected void onRequestStart(String url, boolean isLoading) {
        if (mActivity == null) {
            return;
        }

        InterLoading loading = mActivity.getLoading();
        if (loading != null && isLoading) {
            loading.showLoading();
        }
    }

    /**
     * 请求结束回调
     *
     * @param resultCode 1:成功，0：cancel，-1：失败
     */
    protected void onRequestFinish(String url, int resultCode, boolean isLoading) {
        if (mActivity == null) {
            return;
        }

        InterLoading loading = mActivity.getLoading();
        if (loading != null && isLoading) {
            loading.closeLoading();
        }
    }

    /**
     * 请求失败回调
     *
     * @param url
     * @param isLoading
     * @param exceptionStr
     */
    protected void onRequestFailure(String url, boolean isLoading, String exceptionStr) {
    }

    /**
     * 请求取消回调
     *
     * @param url
     * @param isLoading
     */
    protected void onRequestCancel(String url, boolean isLoading) {
    }

    /**
     * 默认回调。
     *
     * @param <T>
     */
    protected static class BaseCallBack<T> extends CallBack<T> {

        private WeakReference<LKBaseFragment> mRef;

        public BaseCallBack(LKBaseFragment fragment) {
            mRef = new WeakReference<>(fragment);
        }

        @Override
        public void onSuccess(String url, T obj) {
            if (mRef.get() != null) {
                mRef.get().onRequestSuccess(url, obj);
            }
        }

        @Override
        public void onStart(String url, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestStart(url, isLoading);
            }
        }

        @Override
        public void onFailure(String url, boolean isLoading, String exceptionStr) {
            if (mRef.get() != null) {
                mRef.get().onRequestFailure(url, isLoading, exceptionStr);
            }
        }

        @Override
        public void onCancel(String url, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestCancel(url, isLoading);
            }
        }

        /**
         * @param url        请求url
         * @param resultCode 1:成功，0：cancel，-1：失败
         * @param isLoading  是否展示loading
         */
        @Override
        public void onFinish(String url, int resultCode, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestFinish(url, resultCode, isLoading);
            }
        }

        @Override
        public void onUpLoadProgress(String filePath, int progress) {
        }

        @Override
        public void onDownLoadProgress(String url, String filePath, int progress) {
        }

        @Override
        public void onDownLoadFailure(String url, String filePath) {
        }

        @Override
        public void onDownLoadSuccess(String url, String filePath) {
        }

    }

    /**
     * 结束请求
     *
     * @param call
     */
    public final void cancelCall(LKCall call) {
        if (call != null) {
            call.cancel();
        }
    }

    /***************************************************************************/
    /******************************网络相关方法END******************************/
    /***************************************************************************/
    /**
     * 防止内存泄漏handler
     */
    public final static class WeakHandler extends Handler {

        private WeakReference<LKBaseFragment> mRef;


        public WeakHandler(LKBaseFragment activity) {
            super(Looper.getMainLooper());
            this.mRef = new WeakReference<>(activity);
        }

        /**
         * 获取当前activity
         *
         * @return 当前activity.可能为空
         */
        public LKBaseFragment get() {
            if (mRef != null && mRef.get() != null) {
                return mRef.get();
            }
            return null;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            LKBaseFragment t = get();
            if (t != null) {
                t.onHandleMsg(msg);
            }
        }

    }

    /***************************************************************************/

    @Override
    public void onDestroy() {
        super.onDestroy();
        isViewPrepare = false;
        isFirstVisible = true;

        if (mBroadcastReceivers != null && !mBroadcastReceivers.isEmpty()) {
            for (BroadcastReceiver receiver : mBroadcastReceivers) {
                if (receiver != null) {
                    getActivity().unregisterReceiver(receiver);
                }
            }
            mBroadcastReceivers.clear();
            mBroadcastReceivers = null;
        }

        if (mWeakHandler != null) {
            mWeakHandler.removeCallbacksAndMessages(null);
            mWeakHandler = null;
        }
    }
}
